﻿#pragma once

#include <vulkan/vulkan.hpp>

//由于在cpu端准备当前帧时，
//上一帧使用的资源可能还在gpu端使用，
//所以需要一个机制来延迟回收上一帧使用的资源
struct SVulkanRecycleObjects
{
    TVector<vk::CommandBuffer> CommandBuffers;
    TVector<vk::Fence> Fences;
    TVector<vk::Framebuffer> Framebuffers;

    TVector<vk::Buffer> Buffers;
    TVector<vk::Image> Images;
    TVector<SVulkanMemoryBlock> MemoryBlocks;
    TVector<vk::ImageView> ImageViews;
    TVector<vk::DeviceMemory> Memories;

    TVector<vk::ShaderModule> ShaderModules;
    //TODO 添加更多的资源

    void Recycle(
        vk::Device Device
        ,vk::CommandPool InCommandPool
        ,CMemoryPools* MemoryPools
        )
    {
        if(!CommandBuffers.Empty())
        {
            Device.freeCommandBuffers(InCommandPool,CommandBuffers);
        }

        if(!Fences.Empty())
        {
            Device.waitForFences(Fences,true,UINT64_MAX);
            for (auto& Fence : Fences)
            {
                Device.destroyFence(Fence);
            }
        }

        for(auto& Framebuffer: Framebuffers)
        {
            Device.destroyFramebuffer(Framebuffer);
        }

        for(auto& Buffer: Buffers)
        {
            Device.destroyBuffer(Buffer);
        }

        for(auto& Image: Images)
        {
            Device.destroyImage(Image);
        }
   
        for(auto& MemoryBlock: MemoryBlocks)
        {
            if(MemoryBlock.IsValid())
            {
                MemoryPools->DeallocateBlock(MemoryBlock);
            }
        }

        for(auto& ImageView: ImageViews)
        {
            Device.destroyImageView(ImageView);
        }

        for(auto& Memory: Memories)
        {
            Device.freeMemory(Memory);
        }
        
        for(auto& ShaderModule: ShaderModules)
        {
            Device.destroyShaderModule(ShaderModule);
        }



        CommandBuffers.Clear();
        Fences.Clear();
        Framebuffers.Clear();
        Buffers.Clear();
        Images.Clear();
        MemoryBlocks.Clear();
        ImageViews.Clear();
        Memories.Clear();
        ShaderModules.Clear();
    }
   
};